
package radiostation;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import javax.persistence.Query;
import javax.swing.JOptionPane;
import pojos.Album;
import pojos.Artist;
import pojos.Musicgroup;
import pojos.Playlist;
import pojos.Song;

/**
 *
 * @author KATERINA
 */
public class DBmanager {
    private EntityManager db;
    private EntityManagerFactory emf;
    private EntityManager em;

    public DBmanager() {
        
        //Πρέπει να δηλώσουμε τον EntityManager και στον Constructor... 
        //...να τον δημιουργήσουμε. 
        //Η δημιουργία του EntityManager γίνεται μέσω του EntityManagerFactory,...
        //...το οποίο με τη σειρά του δημιουργείται από το Persistence Context...
        //...δίνοντας ως παράμετρο το όνομα του Persistence Unit «ErgasiaTestPU»...
        //...που έχει δημιουργηθεί αυτόματα από το Netbeans
        try { 
            // Δημιουργία του EntityManagerFactory το οποίο συνδέεται στο
            // Persistence Unit που αντιστοιχεί στην Βάση Δεδομένων μας
            emf = Persistence.createEntityManagerFactory("RadioStation_LocalPU");
            // Δημιουργία του EntityManager
            db = emf.createEntityManager();
            this.em = db;
            
        } catch(Exception ex) { 
            JOptionPane.showMessageDialog(null, 
                            "Η ΒΔ δεν είναι συνδεδεμένη.", 
                            "Δεν έγινε σύνδεση με τη ΒΔ.",
                        JOptionPane.WARNING_MESSAGE);
            System.exit(1);
        }
    }
    
    public EntityManager getdb() {
        return db;
    }

  // Βρίσκουμε όλους τουs Καλλιτεχνες
    public ArrayList<Artist> FindAllArtists() { 
        Query FindAllArtists;
         //sql query για την ανάκτηση όλων των Καλλιτεχνες
        FindAllArtists = getdb().createNamedQuery("Artist.findAll",Artist.class);
        return new ArrayList<Artist>(FindAllArtists.getResultList());
    }
 
  // Βρίσκουμε όλα τα Album
    public ArrayList<Album> FindAllAlbums() { 
        Query FindAllAlbums;
         //sql query για την ανάκτηση όλων των Album
        FindAllAlbums = getdb().createNamedQuery("Album.findAll",Album.class);
        return new ArrayList<Album>(FindAllAlbums.getResultList());
    }
    
  // Βρίσκουμε όλα τα Group
    public ArrayList<Musicgroup> FindAllMusicgroups() { 
        Query FindAllMusicgroups;
         //sql query για την ανάκτηση όλων των Group
        FindAllMusicgroups = getdb().createNamedQuery("Musicgroup.findAll",Musicgroup.class);
        return new ArrayList<Musicgroup>(FindAllMusicgroups.getResultList());
    }

   // Βρίσκουμε όλα τα Songs
    public ArrayList<Song> FindAllSongs() { 
        Query FindAllSongs;
         //sql query για την ανάκτηση όλων των Songs
        FindAllSongs = getdb().createNamedQuery("Song.findAll",Song.class);
        return new ArrayList<Song>(FindAllSongs.getResultList());
    }

    // Βρίσκουμε όλα τα Playlist
    public ArrayList<Playlist> FindAllPlaylists() { 
        Query FindAllPlaylists;
         //sql query για την ανάκτηση όλων των Playlist
        FindAllPlaylists = getdb().createNamedQuery("Playlist.findAll",Playlist.class);
        return new ArrayList<Playlist>(FindAllPlaylists.getResultList());
    }
    
    // Συναρτηση για την διατήρηση της ακεραιότητας του ξένου κλειδιού στα άλμπουμ
    public Album getAlbum(Integer albumid){
        Album alb = new Album();       
        Query q = em.createNamedQuery("Album.findById",Album.class);
            q.setParameter("id", albumid);

            if (!em.getTransaction().isActive()) {
                    em.getTransaction().begin();
            } 
            try {
               alb =  (Album)q.getSingleResult();
            } catch (Exception e) {
                System.out.println("Δεν υπαρχει αλμπουμ, επιστρέφει null!!!");
                em.getTransaction().rollback();
            } 
        return alb;
    }
    //Γενική συνάρτηση για εγγραφή οντοτήτων στην ΒΔ. 
    public Boolean insert(Object obj){
        Boolean retval = true;
        if (!em.getTransaction().isActive()) {
                em.getTransaction().begin();
        }  
        if (em.getTransaction().isActive()) {
                try {
                    em.persist(obj);   
                  //  System.out.println("after persist");
                    em.getTransaction().commit();
                   // System.out.println("after commit");
                } catch (Exception e) {
                    //System.out.println("in exception for" + e.getLocalizedMessage());
                    retval = false;
                if (em.getTransaction().isActive()) {
                    em.close();
                }
            }
        } 
        return retval;
    }
    
    //Validation των τραγουδιών και της λίστας από το αρχείο της XML λίστας. 
    public Boolean validate(Playlist pl){
        
        List<Song> songList = new ArrayList<>(0);        
        for (Song s : pl.getSongList()){
            songList.add(s);
        }
        pl.getSongList().clear();
        
        try {
            if (!em.getTransaction().isActive()) {
                    em.getTransaction().begin();
            }
            em.persist(pl);
            em.flush();
            for ( Song s :  songList) {

                if (em.getTransaction().isActive()) {
                        try {

                            s = em.find(Song.class,s.getId()); 
                            pl.getSongList().add(s);
                            em.merge(s);
                            em.merge(pl);                            
                        } catch (Exception e) {
                            //System.out.println("in exception for" + e.getLocalizedMessage());
                            s = null;
                            if (em.getTransaction().isActive()) {
                                em.close();
                            }
                        }
                }
            }
            em.getTransaction().commit();
            
            return true;
        } catch (Exception e) {
            JOptionPane.showMessageDialog(null,"Το αρχείο XML έχει πρόβλημα...");
            return false;
        }
    }
}
